home *** CD-ROM | disk | FTP | other *** search
/ Hackers Handbook - Millenium Edition / Hackers Handbook.iso / library / hack / watch_root.txt < prev    next >
Encoding:
Text File  |  1998-08-24  |  13.4 KB  |  304 lines

  1. [ http://www.rootshell.com/ ]
  2.  
  3.                    From emoc@vortex.misterweb.com Fri Aug  7 11:42:42 1998
  4.                    Date: Thu, 6 Aug 1998 14:39:48 -0500 (EST)
  5.                    From: Matthew George <emoc@vortex.misterweb.com>
  6.                    To: submission@rootshell.com
  7.  
  8.                    #!/usr/bin/perl -w
  9.  
  10.                    ## sysmon.pl
  11.                    ## Author: emoc <emoc@misterweb.com>
  12.  
  13.                    ## This script, run on a regular (daily) basis, keeps tabs
  14.                    ## on root accounts and set[ug]id root files. Output includes:
  15.                    ##  list of all uid/gid 0 (or 131072) accounts
  16.                    ##  list of all set[ug]id 0 files
  17.                    ##  root accounts that have been added, changed, or deleted since last run
  18.                    ##  set[ug]id 0 files that have been added, changed (incl. size), or deleted since last run
  19.  
  20.                    ## By default, it will mail the results to root.
  21.                    ## It would be best to invoke it from root's cron using:
  22.                    ## 0 0 * * * /path/to/sysmon.pl
  23.  
  24.  
  25.                    ########################
  26.                    ### User Definitions ###
  27.                    ########################
  28.  
  29.                    # [0/1] Do we have a shadow password setup (assumes /etc/shadow)?
  30.                    # Enabling this means that the script will process information from /etc/shadow.
  31.                    # It will enable the script to see if passwords on root accounts have changed,
  32.                    # but if you don't want it touching the shadow file, just set to 0
  33.                    $USE_SHADOW = 1;
  34.  
  35.                    # [0/1] This will disable the mail to root and simply display the
  36.                    # results of the script to STDOUT
  37.                    $NOMAIL = 0;
  38.  
  39.  
  40.                    ############
  41.                    ### Code ###
  42.                    ############
  43.  
  44.  
  45.                    # open /etc/passwd (and /etc/shadow if defined above) and pull all root acct info
  46.                    open(PWD, "/etc/passwd") || die("open /etc/passwd: $!");
  47.                    while (<PWD>) {
  48.  
  49.                            # also checks for uid / gid 131072, which can be interpreted as 0
  50.                            if ((/.*:0:.*/) || (/.*:131072:.*/)) {
  51.                                    chomp;
  52.                                    $data = $_;
  53.                                    s/:.*//;
  54.                                    $login = $_;
  55.                    #D cpinfo -> npinfo
  56.                                    $npinfo{$login} = $data;
  57.  
  58.                                    if ($USE_SHADOW) {
  59.  
  60.                                            open(SHADOW, "/etc/shadow") || die("open /etc/shadow: $!");
  61.                                            while (<SHADOW>) {
  62.  
  63.                                                    if (/$login/) {
  64.                                                            chomp;
  65.                                                            $nsinfo{$login} = $_;
  66.                    #D cpinfo -> npinfo on rt of =
  67.                                                            $npinfo{$login} = $npinfo{$login} . "\n" . $_
  68.                                                    }
  69.                                            }
  70.                                            close(SHADOW) || die("close /etc/shadow: $!");
  71.  
  72.                    #D              } else {
  73.                    #D                      $npinfo{$login} = $cpinfo{$login}
  74.                                    }
  75.                            }
  76.                    }
  77.                    close(PWD) || die("close /etc/passwd: $!");
  78.  
  79.  
  80.                    ### END Acct. checks
  81.                    ### BEGIN set[ug]id 0 checks
  82.  
  83.                    sub checkperms {
  84.  
  85.                            if ( -u $file) {
  86.                                    $uid = (stat($file))[4];
  87.                                    if ($uid == 0) {
  88.                                            $nsulist{$file} = `ls -dl $file`;
  89.                                            chomp($nsulist{$file});
  90.                                            return 1;
  91.                                    }
  92.  
  93.                            } elsif ( -g $file) {
  94.                                    $gid = (stat($file))[5];
  95.                                    if ($gid == 0) {
  96.                                            $nsglist{$file} = `ls -dl $file`;
  97.                                            chomp($nsglist{$file});
  98.                                            return 1;
  99.                                    }
  100.                            }
  101.                            
  102.                            return 0;
  103.                    }
  104.  
  105.  
  106.                    $dirlist[0] = "";
  107.                    foreach $dir (@dirlist) {
  108.  
  109.                            foreach $file (<${dir}/*>) {
  110.                                    # turn all those nasty little quotes and ticks in filenames into literals that sh can parse a bit more cleanly
  111.                                    $file =~ s/\'/\\\'/;
  112.                                    $file =~ s/\"/\\\"/;
  113.                                    $file =~ s/\`/\\\`/;
  114.  
  115.                                    # directories (excluding proc) that aren't links
  116.                                    if (( -d $file) && ($file ne "/proc") && (! -l $file)) {
  117.                                            checkperms();
  118.                                            push(@dirlist, $file);
  119.  
  120.                                    # set[ug]id files that aren't links
  121.                                    } elsif ((( -u $file) || ( -g $file)) && (! -l $file)) {
  122.                                            checkperms();
  123.                                    }
  124.                            }
  125.  
  126.                            # same with everything that starts w/ a .
  127.                            foreach $file (<${dir}/.*>) {
  128.  
  129.                                    # make sure we aren't looking at */. or */.. as well
  130.                                    if (( -d $file) && (! -l $file) && (! (($file =~ m#/\.$#) || ($file =~ m#/(\.)\1$#)))) {
  131.                                            checkperms();
  132.                                            push(@dirlist, $file);
  133.  
  134.                                    } elsif ((( -u $file) || ( -g $file)) && ((! -l $file) && (! (($file =~ m#/\.$#) || ($file =~ m#/(\.)\1$#))))) {
  135.                                            checkperms();
  136.                                    }
  137.                            }
  138.                    }
  139.  
  140.  
  141.                    if (! $NOMAIL) {
  142.                            open(MAIL, "|mail root") || die("open mail: $!");
  143.                            select(MAIL);
  144.                    }
  145.  
  146.  
  147.                    dbmopen(%pinfo, "/var/log/pinfo", 0600) || die("dbmopen pinfo: $!");
  148.  
  149.                    print("="x20, "\n");
  150.                    print("Root accounts which have been added or changed since last check:\n\n");
  151.                    foreach $login (sort keys %npinfo) {
  152.                            if (! $pinfo{$login}) {
  153.                                    print("$login (old):\n", "NON-EXISTANT\n\n");
  154.                                    print("$login (new):\n", "$npinfo{$login}\n\n");
  155.                                    $pinfo{$login} = $npinfo{$login};
  156.  
  157.                            } elsif ($npinfo{$login} ne $pinfo{$login}) {
  158.                                    print("$login (old):\n");
  159.                                    print("$pinfo{$login}\n\n");
  160.                                    print("$login (new):\n");
  161.                                    print("$npinfo{$login}\n\n");
  162.                                    $pinfo{$login} = $npinfo{$login};
  163.                            }
  164.                    }
  165.  
  166.  
  167.                    print("="x20, "\n");
  168.                    print("Root accounts which have been deleted since last check:\n");
  169.                    foreach $login (sort keys %pinfo) {
  170.                            if (! $npinfo{$login}) {
  171.                                    print("$login:\n");
  172.                                    print("$pinfo{$login}\n\n");
  173.                                    delete($pinfo{$login});
  174.                            }
  175.                    }
  176.                    print("\n");
  177.  
  178.  
  179.                    dbmclose(%pinfo);
  180.                    dbmopen(%sulist, "/var/log/sulist", 0600);
  181.  
  182.                    print("="x20, "\n");
  183.                    print("Files that have changed or had setuid privileges added since last check:\n");
  184.                    foreach $file (sort keys %nsulist) {
  185.                            if (! $sulist{$file}) {
  186.                                    print("$file (old):\n");
  187.                                    print("NON-EXISTANT\n");
  188.                                    print("$file (new):\n");
  189.                                    print($nsulist{$file}, "\n\n");
  190.                                    $sulist{$file} = $nsulist{$file};
  191.  
  192.                            } elsif ($nsulist{$file} ne $sulist{$file}) {
  193.                                    print("$file (old):\n");
  194.                                    print($sulist{$file}, "\n");
  195.                                    print("$file (new):\n");
  196.                                    print($nsulist{$file}, "\n\n");
  197.                                    $sulist{$file} = $nsulist{$file};
  198.                            }
  199.                    }
  200.                    print("\n");
  201.  
  202.  
  203.                    print("="x20, "\n");
  204.                    print("Files that have been moved, renamed, deleted, or had setuid privileges dropped:\n");
  205.                    foreach $file (sort keys %sulist) {
  206.                            if (! $nsulist{$file}) {
  207.                                    print("$file (old):\n");
  208.                                    print($sulist{$file}, "\n");
  209.                                    print("$file (new):\n");
  210.                                    if ( -e $file) {
  211.                                            $nv = `ls -dl $file`;
  212.                                            chomp($nv);
  213.                                            print($nv, "\n\n")
  214.                                    } else {
  215.                                            print("MOVED, RENAMED, OR DELETED\n\n");
  216.                                    }
  217.                                    delete($sulist{$file});
  218.                            }
  219.                    }
  220.                    print("\n");
  221.  
  222.                    dbmclose(%sulist);
  223.                    dbmopen(%sglist, "/var/log/sglist", 0600);
  224.  
  225.                    print("="x20, "\n");
  226.                    print("Files that have changed or had setgid privileges added since last check:\n");
  227.                    foreach $file (sort keys %nsglist) {
  228.                            if (! $sglist{$file}) {
  229.                                    print("$file (old):\n");
  230.                                    print("NON-EXISTANT\n");
  231.                                    print("$file (new):\n");
  232.                                    print($nsglist{$file}, "\n\n");
  233.                                    $sglist{$file} = $nsglist{$file};
  234.  
  235.                            } elsif ($nsglist{$file} ne $sglist{$file}) {
  236.                                    print("$file (old):\n");
  237.                                    print($sglist{$file}, "\n");
  238.                                    print("$file (new):\n");
  239.                                    print($nsglist{$file}, "\n\n");
  240.                                    $sglist{$file} = $nsglist{$file};
  241.                            }
  242.                    }
  243.                    print("\n");
  244.  
  245.                    print("="x20, "\n");
  246.                    print("Files that have been moved, renamed, deleted, or had setgid privileges dropped:\n");
  247.                    foreach $file (sort keys %sglist) {
  248.                            if (! $nsglist{$file}) {
  249.                                    print("$file (old):\n");
  250.                                    print($sglist{$file}, "\n");
  251.                                    print("$file (new):\n");
  252.                                    if ( -e $file) {
  253.                                            $nv = `ls -dl $file`;
  254.                                            chomp($nv);
  255.                                            print($nv, "\n\n")
  256.                                    } else {
  257.                                            print("MOVED, RENAMED, OR DELETED\n\n");
  258.                                    }
  259.                                    delete($sglist{$file});
  260.                            }
  261.                    }
  262.                    print("\n");
  263.  
  264.                    dbmclose(%sglist);
  265.  
  266.  
  267.                    print("="x20, "\n");
  268.                    open(DF, "df|");
  269.                    print(<DF>, "\n");
  270.                    close(DF);
  271.  
  272.  
  273.                    print("="x20, "\n");
  274.                    print("Users with either uid or gid 0 or 131072:\n\n");
  275.                    #D cpinfo -> npinfo
  276.                    foreach (sort keys %npinfo) {
  277.                            if ($USE_SHADOW) {
  278.                    #D cpinfo -> npinfo
  279.                                    print($_, "\n", $npinfo{$_}, "\n", $nsinfo{$_}, "\n\n")
  280.                            } else {
  281.                    #D cpinfo -> npinfo
  282.                                    print($_, "\n", $npinfo{$_}, "\n\n")
  283.                            }
  284.                    }
  285.  
  286.  
  287.                    print("="x20, "\n");
  288.                    print("setuid root files:\n");
  289.                    foreach (sort keys %nsulist) {
  290.                            print("$nsulist{$_}\n");
  291.                    }
  292.                    print("\n");
  293.  
  294.                    print("="x20, "\n");
  295.                    print("setgid root files that aren\'t setuid:\n");
  296.                    foreach (sort keys %nsglist) {
  297.                            print("$nsglist{$_}\n");
  298.                    }
  299.                    print("\n");
  300.  
  301.  
  302.                    if (! $NOMAIL) {
  303.                            close(MAIL);
  304.                    }